import configs
import logging

__author__ = 'YOTAM'

import httplib2
from apiclient.discovery import build
import oauth2client.client as client
import datetime
from oauth2client import GOOGLE_TOKEN_URI

class GoogleCalendar:

    def __init__(self):
        pass

    DAY_FORMAT = "%Y-%m-%d"
    FULL_FORMAT = "%Y-%m-%dT%H:%M:%SZ"

    @staticmethod
    def build_service(credentials):
        logging.info("create service")
        http = httplib2.Http()
        http = credentials.authorize(http)
        service = build('calendar', 'v3')
        return http, service

    @staticmethod
    def update_tokens(bi, credentials):
        dirty = False
        if bi.access_token != credentials.access_token:
            dirty = True
            bi.access_token = credentials.access_token
        if bi.token_expires != credentials.token_expiry:
            dirty = True
            bi.token_expires = credentials.token_expiry
        if dirty:
            logging.info("updating tokens to db")
            bi.put()

    @staticmethod
    def create_credentials(bi):
        logging.info("create credentials with: refresh_token: %s, access_token: %s, expiry: %s" % (bi.refresh_token, bi.access_token, bi.token_expires))
        credentials = client.OAuth2Credentials(bi.access_token, configs.WEB_CLIENT_ID, configs.CLIENT_SECRET,
                                               bi.refresh_token, bi.token_expires,
                                               GOOGLE_TOKEN_URI, 'showup/1.0')
        return credentials

    @staticmethod
    def create_appointment(apt, bi):

        logging.info("create google calendar appointment")

        credentials = GoogleCalendar.create_credentials(bi)

        http, service = GoogleCalendar.build_service(credentials)

        start = datetime.datetime.utcfromtimestamp(apt.start_time)
        end = datetime.datetime.utcfromtimestamp(apt.start_time + apt.duration)
        timezone = "Asia/Jerusalem"

        event_body = {
            "summary": apt.title,
            "start": {"dateTime": start.strftime( GoogleCalendar.FULL_FORMAT), "timeZone": timezone},
            "end": {"dateTime": end.strftime( GoogleCalendar.FULL_FORMAT), "timeZone": timezone},
            "status": "confirmed",
            "transparency": "opaque"
        }

        if apt.repeated and apt.repeated > 0:
            if apt.repeated == 1 or apt.repeated == 7 or apt.repeated == 14:
                event_body["recurrence"] = ["RRULE:FREQ=DAILY;INTERVAL=%d" % apt.repeated]
            elif apt.repeated == 31:
                event_body["recurrence"] = ["RRULE:FREQ=MONTHLY;INTERVAL=1"]
            elif apt.repeated == 365:
                event_body["recurrence"] = ["RRULE:FREQ=YEARLY;INTERVAL=1"]

        if apt.notes:
            event_body["description"] = apt.notes

        logging.info("call service insert with body: %s" % event_body)
        q = service.events().insert(calendarId="primary", body=event_body)
        result = q.execute(http=http)
        logging.info("result id: %s, result: %s" % (result["id"], result))


        GoogleCalendar.update_tokens(bi, credentials)
        return result["id"]


    @staticmethod
    def edit_appointment(apt, bi):
        logging.info("edit google calendar appointment")

        credentials = GoogleCalendar.create_credentials(bi)

        http, service = GoogleCalendar.build_service(credentials)

        start = datetime.datetime.utcfromtimestamp(apt.start_time)
        end = datetime.datetime.utcfromtimestamp(apt.start_time + apt.duration)
        timezone = "Asia/Jerusalem"

        event_body = {
            "summary": apt.title,
            "start": {"dateTime": start.strftime( GoogleCalendar.FULL_FORMAT), "timeZone": timezone},
            "end": {"dateTime": end.strftime( GoogleCalendar.FULL_FORMAT), "timeZone": timezone},
            "status": "confirmed",
            "transparency": "opaque"
        }

        if apt.repeated and apt.repeated > 0:
            if apt.repeated == 1 or apt.repeated == 7 or apt.repeated == 14:
                event_body["recurrence"] = ["RRULE:FREQ=DAILY;INTERVAL=%d" % apt.repeated]
            elif apt.repeated == 31:
                event_body["recurrence"] = ["RRULE:FREQ=MONTHLY;INTERVAL=1"]
            elif apt.repeated == 365:
                event_body["recurrence"] = ["RRULE:FREQ=YEARLY;INTERVAL=1"]

        if apt.notes:
            event_body["description"] = apt.notes

        logging.info("call service patch with eventId %s body: %s" % (apt.remote_id, event_body))

        q = service.events().patch(calendarId="primary", eventId=apt.remote_id,
                                        body=event_body, sendNotifications=True)
        result = q.execute(http=http)
        logging.info("result id: %s, result: %s" % (result["id"], result))

        GoogleCalendar.update_tokens(bi, credentials)
        return result["id"]


    @staticmethod
    def delete_appointment(apt, bi):
        logging.info("delete google calendar appointment")

        credentials = GoogleCalendar.create_credentials(bi)
        http, service = GoogleCalendar.build_service(credentials)

        logging.info("call service delete with eventId %s" % apt.remote_id)

        q = service.events().delete(calendarId='primary', eventId=apt.remote_id, sendNotifications=True);
        result = q.execute(http=http)
        logging.info("result: %s" % result)

        GoogleCalendar.update_tokens(bi, credentials)
